#include "gstreamer_7.h"

void play_06(int argc, char *argv[])
{
    GstElement *pipeline, *audio_source, *tee;
    GstElement *audio_queue, *audio_convert, *audio_resample, *audio_sink;
    GstElement *video_queue, *visual, *video_convert, *video_sink;

    GstBus *bus;
    GstMessage *message;

    GstPad *tee_audio_pad, *tee_video_pad;
    GstPad *queue_audio_pad, *queue_video_pad;

    gst_init(&argc, &argv);

    audio_source = gst_element_factory_make("audiotestsrc", "audio_source");
    tee = gst_element_factory_make("tee", "tee");

    audio_queue = gst_element_factory_make("queue", "audio_queue");
    audio_convert = gst_element_factory_make("audioconvert", "audio_convert");
    audio_resample = gst_element_factory_make("audioresample", "audio_resample");
    audio_sink = gst_element_factory_make("autoaudiosink", "audio_sink");

    video_queue = gst_element_factory_make("queue", "video_queue");
    visual = gst_element_factory_make("wavescope", "visual");
    video_convert = gst_element_factory_make("videoconvert", "csp");
    video_sink = gst_element_factory_make("autovideosink", "video_sink");

    pipeline = gst_pipeline_new("test-pipeline");

    if (!pipeline || !audio_source || !tee || !audio_queue || !audio_convert || !audio_resample || !audio_sink || !video_queue || !visual || !video_convert || !video_sink)
    {
        g_printerr("Not all elements could be created.\n");
        return;
    }

    g_object_set(audio_source, "freq", 215.0f,nullptr);
    g_object_set(visual, "shader", 0, "style", 1, nullptr);

    gst_bin_add_many(GST_BIN(pipeline), audio_source, tee, audio_queue, audio_convert, audio_resample, audio_sink, video_queue, visual, video_convert, video_sink, nullptr);
    if(gst_element_link_many(audio_source, tee, nullptr) != true ||
    gst_element_link_many(audio_queue, audio_convert, audio_resample, audio_sink, nullptr) != true ||
    gst_element_link_many(video_queue, visual, video_convert, video_sink, nullptr) != true) {
        g_printerr("Elements could not be linked.\n");
        return;
    }

    tee_audio_pad = gst_element_request_pad_simple(tee, "src_%u");
    g_print("Obtained request pad %s for audio branch.\n", gst_pad_get_name(tee_audio_pad));
    queue_audio_pad = gst_element_get_static_pad(audio_queue, "sink");

    tee_video_pad = gst_element_request_pad_simple(tee, "src_%u");
    g_print("Obtained request pad %s for video branch.\n", gst_pad_get_name(tee_video_pad));
    queue_video_pad = gst_element_get_static_pad(video_queue, "sink");

    if(gst_pad_link(tee_audio_pad, queue_audio_pad) != GST_PAD_LINK_OK ||
    gst_pad_link(tee_video_pad, queue_video_pad) != GST_PAD_LINK_OK) {
        g_printerr("tee could be linked.\n");
        g_object_unref(pipeline);
        return;
    }
    g_object_unref(queue_audio_pad);
    g_object_unref(queue_video_pad);

    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    bus = gst_element_get_bus(pipeline);
    message = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR |GST_MESSAGE_EOS));

    gst_element_release_request_pad(tee, tee_audio_pad);
    gst_element_release_request_pad(tee, tee_video_pad);
    gst_object_unref(tee_audio_pad);
    gst_object_unref(tee_video_pad);

    if(message) {
        gst_message_unref(message);
    }
    g_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    g_object_unref(pipeline);

}
